package com.game.model;

import com.game.global.Const;
import com.game.global.CrashType;
import com.game.interfaces.Blast;
import com.game.interfaces.CollisionAble;
import com.game.interfaces.LifeCycle;
import com.game.main.GameContext;

import java.awt.*;
import java.util.concurrent.atomic.AtomicBoolean;

/**
 * Created by tjc on 2019-4-29.
 *
 * @auther: tjc
 * @Date: 2019-4-29
 */
public abstract class Tank extends Module implements CollisionAble, LifeCycle {

    public static final int T_ENEMY = 0;
    public static final int T_HERO = 1;

    int health = 1;
    AtomicBoolean alive;

    protected int MAX_bullet_NUM = 1;

    int curDirection;
    
    public Tank() {
    }

    public void init() {
        alive = new AtomicBoolean(true);
    }

    public abstract void move();

    public abstract void start();

    boolean isBlocking() {
        //todo 待优化 每次移动都需要和所有墙壁判定是否碰撞
        GameContext ct = GameContext.getContext();
        for (Border b : ct.getBorderList()) {
            if (checkCollision(b)) {
                return true;
            }
        }

        for (Wall w : ct.getWallList()) {
            if (checkCollision(w)) {
                return true;
            }
        }
        for (Tank t : ct.getTankList()) {
            if (t != this && checkCollision(t)) {
                return true;
            }
        }
        return false;
    }

    boolean checkCollision(CollisionAble o) {
        if (this.futureRect().intersects(o.getRec()) && frontBlocking(o)) {
            return true;
        }
        return false;
    }

    /**
     * 坦克前方碰撞
     */
    boolean frontBlocking(CollisionAble o) {
        if (o.getLocalX() >= this.getRight() && this.curDirection == Const.DIRECTION_RIGHT) {
            return true;
        }
        if (o.getLocalY() >= this.getBottom() && this.curDirection == Const.DIRECTION_DOWN) {
            return true;
        }
        if (o.getRight() <= this.getLocalX() && this.curDirection == Const.DIRECTION_LEFT) {
            return true;
        }
        if (o.getBottom() <= this.getLocalY() && this.curDirection == Const.DIRECTION_UP) {
            return true;
        }
        return false;
    }

    public void shoot() {
        Bullet bullet = null;
        switch (curDirection) {
            case Const.DIRECTION_UP:
                bullet = new Bullet(localX + SIZE_X / 2, localY, this.curDirection, this);
                break;
            case Const.DIRECTION_DOWN:
                bullet = new Bullet(localX + SIZE_X / 2, localY + SIZE_Y, this.curDirection, this);
                break;
            case Const.DIRECTION_LEFT:
                bullet = new Bullet(localX, localY + SIZE_Y / 2, this.curDirection, this);
                break;
            case Const.DIRECTION_RIGHT:
                bullet = new Bullet(localX + SIZE_X, localY + SIZE_Y / 2, this.curDirection, this);
                break;
            default:
        }
        java.util.List<Bullet> bulletList = GameContext.getContext().bulletList;
        synchronized (bulletList) {
            bulletList.add(bullet);
            bullet.init();
        }
//        shotBullets.add(bullet);
    }

    public abstract void draw(Graphics g);

    public Rectangle getRec() {
        return new Rectangle(localX, localY, SIZE_X, SIZE_Y);
    }

    @Override
    public int getCollisionType() {
        return CrashType.TANK;
    }

    private Rectangle futureRect() {
        switch (this.curDirection) {
            case Const.DIRECTION_UP:
                return new Rectangle(localX, localY - speed - 1, SIZE_X, SIZE_Y);
            case Const.DIRECTION_DOWN:
                return new Rectangle(localX, localY + speed + 1, SIZE_X, SIZE_Y);
            case Const.DIRECTION_LEFT:
                return new Rectangle(localX - speed - 1, localY, SIZE_X, SIZE_Y);
            case Const.DIRECTION_RIGHT:
                return new Rectangle(localX + speed + 1, localY, SIZE_X, SIZE_Y);
        }
        return null;
    }

    public void hurt(int attack) {
        health = health - attack;
        if (health <= 0) {
            this.destroy();
        }
    }

//    public void removeBullet(Bullet bullet) {
//        shotBullets.remove(bullet);
//    }

    @Override
    public void destroy() {
        alive.set(false);
        java.util.List<Blast> blastList = GameContext.getContext().blastList;

        synchronized (blastList) {
            TankBlast blast = new TankBlast(localX, localY);
            blastList.add(blast);
            blast.init();
        }
    }

//    public List<Bullet> getBulletList() {
//        return shotBullets;
//    }

    public abstract int getTankType();

    public int getBottom() {
        return this.getLocalY() + SIZE_Y;
    }

    public int getRight() {
        return this.getLocalX() + SIZE_X;
    }

    public boolean alive() {
        return alive.get();
    }


    public int getLocalX() {
        return localX;
    }

    public void setLocalX(int localX) {
        this.localX = localX;
    }

    public int getLocalY() {
        return localY;
    }

    public void setLocalY(int localY) {
        this.localY = localY;
    }

    public int getSpeed() {
        return speed;
    }

    public int getDirection() {
        return this.curDirection;
    }

    public void setDirection(int direction) {
        this.curDirection = direction;
    }
}
